﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Data;
using MySql.Data.MySqlClient;
using Model.App;

using SQLWrapper;
using BartonExtension;

using Services.Common;
using Services.PushNotification;

namespace Services.Messages
{
    public class ISMPrivateMessageServiceProvider : ISMServiceProvider
    {
        public const string GET_PRIVATE_MSGS = "get_private_msgs";
        public const string SEND_PRIVATE_MSGS = "send_private_msgs";
        public const string UPDATE_MSGS_RECV_TIMETAG = "update_msgs_recv_tag";
        public const string DID_MSG_RECVED = "did_msg_recved";
        public const string LOAD_THREAD_PM = "load_thread_pm";
        public override Task<ISMServiceResult> doProcess(ISMServiceModel model)
        {
            if(model.operationIdentifier.Equals(GET_PRIVATE_MSGS))
            {
                ISMGetPrivateMsgRequest request = model.GetState<ISMGetPrivateMsgRequest>();
                return GetPrivateMessage(request);
            }
            else if(model.operationIdentifier.Equals(SEND_PRIVATE_MSGS))
            {
                ISMPrivateMessageRequest request = model.GetState<ISMPrivateMessageRequest>();
                return SendPrivateMessage(request);
            }
            else if(model.operationIdentifier.Equals(UPDATE_MSGS_RECV_TIMETAG))
            {
                ISMRecvRecipRequest request = model.GetState<ISMRecvRecipRequest>();
                return UpdateMessageReceiveTimetag(request);
            }
            else if (model.operationIdentifier.Equals(DID_MSG_RECVED))
            {
                ISMRecvRecipRequest request = model.GetState<ISMRecvRecipRequest>();
                return TagMessageReceviced(request);
            }
            else if(model.operationIdentifier.Equals(LOAD_THREAD_PM))
            {
                ISMGetThreadPMsRequest request = model.GetState<ISMGetThreadPMsRequest>();
                return GetThreadPMs(request);
            }
            return base.defaultProcess();
        }
        private Task<ISMServiceResult> GetPrivateMessage(ISMGetPrivateMsgRequest request)
        {
            return Task.Factory.StartNew<ISMServiceResult>(() =>
                {
                    ISMServiceResult result = new ISMServiceResult();
                    MySQLOperationManager.doSQLOperationWithLoadedData(cmd =>
                        {
                            cmd.CommandText = "proc_client_get_private_messages";
                            cmd.Parameters.Add("?_uid", request.uid, ParameterDirection.Input);
                            cmd.Parameters.Add("?_token", request.token, ParameterDirection.Input);
                        },
                        e =>
                        {
                            if(e != null)
                            {
                                result.isOperationSuccess = false;
                                result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ISM_EXCEPTION_ERR;
                                result.errorMsg = e;
                            }
                        },
                        data =>
                        {
                            if (data.Count == 1 && data.First().ContainsKey("error"))
                            {
                                result.isOperationSuccess = false;
                                result.errorMsg = "Token 验证失败";
                                result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ISM_TOKEN_ERROR;
                            }
                            else
                            {
                                List<ISMPrivateMessage> pms = new List<ISMPrivateMessage>();
                                data.ForEach(d =>
                                    {
                                        ISMPrivateMessage pm = new ISMPrivateMessage()
                                        {
                                            from = new ISMUserinfo()
                                            {
                                                ID = d["uid"].toInt64().Value,
                                                openId = d["openid"].ToString(),
                                                intopenid = d["intopenid"].toUInt64().Value.ToString(),
                                                wechatName = d["wechatname"].ToString(),
                                                username = d["username"].ToString(),
                                                sex = d["sex"].toEnum<Sex>(),
                                                vocation = d["vocation"].ToString(),
                                                company = d["company"].ToString(),
                                                occupation = d["occupation"].ToString(),
                                                mobile = d["mobile"].ToString(),
                                                telephone = d["telephone"].ToString(),
                                                email = d["email"].ToString(),
                                                officeAddress = d["officeaddress"].ToString(),
                                                piccardUrl = d["piccardUrl"].ToString(),
                                                videocardUrl = d["videocardUrl"].ToString(),
                                                headimgUrl = d["headimgUrl"].ToString()
                                            },
                                            to = d["to"].toUInt64().Value,
                                            context = d["context"].ToString(),
                                            timetag = d["timetag"].ToString()
                                        };
                                        pms.Add(pm);
                                    });
                                result.dbReturningState = pms;
                            }
                        }, CommandType.StoredProcedure, false);
                    return result;
                });
        }
        private Task<ISMServiceResult> SendPrivateMessage(ISMPrivateMessageRequest request)
        {
            return Task.Factory.StartNew<ISMServiceResult>(() =>
                {
                    ISMServiceResult result = new ISMServiceResult();
                    MySQLOperationManager.doSQLOperation(cmd =>
                        {
                            cmd.CommandText = "proc_client_send_private_message";
                            cmd.Parameters.Add("?_fromid", request.from, ParameterDirection.Input);
                            cmd.Parameters.Add("?_toid", request.to, ParameterDirection.Input);
                            cmd.Parameters.Add("?_context", request.context, ParameterDirection.Input);
                            cmd.Parameters.Add("?_type", request.pmtype, ParameterDirection.Input);
                            cmd.Parameters.Add("?_recvTag", request.isReceived, ParameterDirection.Input);
                            cmd.Parameters.Add("?_token", request.token, ParameterDirection.Input);
                            cmd.Parameters.Add("?errorcode", MySqlDbType.Int32, ParameterDirection.Output);
                            cmd.ExecuteNonQuery();
                            int errorcode = cmd.Parameters["?errorcode"].Value.toInt32().Value;
                            if(errorcode == -1)
                            {
                                result.isOperationSuccess = false;
                                result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ISM_TOKEN_ERROR;
                                result.errorMsg = "Token 验证失败";
                            }
                            else if(errorcode == -2)
                            {
                                result.isOperationSuccess = false;
                                result.errorMsg = "不允许发重复内容";
                                result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_PM_DUMPLICATED_PM;
                            }
                            else if(errorcode == 0)
                            {
                                ISMPushContent content = new ISMPushContent()
                                {
                                    receiverId = request.to.ToString(),
                                    type = ISMPushType.kPushTypePrivateMessage,
                                    fromId = request.from.ToString(),
                                    title = "新的私信",
                                    context = request.context
                                };
                                Pusher.Push(content);
                            }
                        },
                        e =>
                        {
                            if(e != null)
                            {
                                result.isOperationSuccess = false;
                                result.errorMsg = e;
                                result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ISM_EXCEPTION_ERR;
                            }
                        },CommandType.StoredProcedure,false);
                    return result;
                });
        }
        private Task<ISMServiceResult> UpdateMessageReceiveTimetag(ISMRecvRecipRequest request)
        {
            return Task.Factory.StartNew<ISMServiceResult>(() =>
                {
                    ISMServiceResult result = new ISMServiceResult();
                    MySQLOperationManager.doSQLOperation(cmd =>
                        {
                            cmd.CommandText = "proc_client_update_private_message_receivetag";
                            cmd.Parameters.Add("?_uid",request.uid,ParameterDirection.Input);
                            cmd.Parameters.Add("?_token",request.token,ParameterDirection.Input);
                            cmd.Parameters.Add("?errorcode",MySqlDbType.Int32,ParameterDirection.Output);
                            cmd.ExecuteNonQuery();
                            int errorcode = cmd.Parameters["?errorcode"].Value.toInt32().Value;
                            if(errorcode == -1)
                            {
                                result.isOperationSuccess = false;
                                result.errorMsg = "Token 验证失败";
                                result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ISM_TOKEN_ERROR;
                            }
                        },
                        e =>
                        {
                            if(e != null)
                            {
                                result.isOperationSuccess = false;
                                result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ISM_EXCEPTION_ERR;
                                result.errorMsg = e;
                            }
                        }, CommandType.StoredProcedure, false);
                    return result;
                });
        }
        private Task<ISMServiceResult> TagMessageReceviced(ISMRecvRecipRequest request)
        {
            return Task.Factory.StartNew<ISMServiceResult>(() =>
            {
                ISMServiceResult result = new ISMServiceResult();
                MySQLOperationManager.doSQLOperation(cmd =>
                    {
                        cmd.CommandText = "proc_client_update_private_message_receivetag";
                        cmd.Parameters.Add("?_uid", request.uid,ParameterDirection.Input);
                        cmd.Parameters.Add("?_token", request.token, ParameterDirection.Input);
                        cmd.Parameters.Add("?errorcode", MySqlDbType.Int32, ParameterDirection.Output);
                        cmd.ExecuteNonQuery();
                        int errorcode = cmd.Parameters["?errorcode"].Value.toInt32().Value;
                        if(errorcode == -1)
                        {
                            result.isOperationSuccess = false;
                            result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ISM_TOKEN_ERROR;
                            result.errorMsg = "Token 验证失败";
                        }
                    },
                    e =>
                    {
                        if(e != null)
                        {
                            result.isOperationSuccess = false;
                            result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ISM_EXCEPTION_ERR;
                            result.errorMsg = e;
                        }
                    }, CommandType.StoredProcedure, false);
                return result;
            });
        }
        private Task<ISMServiceResult> GetThreadPMs(ISMGetThreadPMsRequest request)
        {
            return Task.Factory.StartNew<ISMServiceResult>(() =>
            {
                ISMServiceResult result = new ISMServiceResult();
                MySQLOperationManager.doSQLOperationWithLoadedData(cmd =>
                    {
                        cmd.CommandText = "proc_client_get_thread_pms";
                        cmd.Parameters.Add("?_timetag", request.timetag, ParameterDirection.Input);
                        cmd.Parameters.Add("?_talk_to", request.talk_to, ParameterDirection.Input);
                        cmd.Parameters.Add("?_uid", request.uid, ParameterDirection.Input);
                        cmd.Parameters.Add("?_token", request.token, ParameterDirection.Input);
                    },
                    e =>
                    {
                        if(e != null)
                        {
                            result.isOperationSuccess = false;
                            result.errorMsg = e;
                            result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ISM_EXCEPTION_ERR;
                        }
                    },
                    data =>
                    {
                        if(data.Count == 1 && data.First().ContainsKey("no_talk"))
                        {
                            result.isOperationSuccess = false;
                            result.errorMsg = "未知错误";
                            result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ISM_UNKNOWN_ERR;
                        }
                        else if(data.Count == 1 && data.First().ContainsKey("error"))
                        {
                            result.isOperationSuccess = false;
                            result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ISM_TOKEN_ERROR;
                            result.errorMsg = "Token 验证失败";
                        }
                        else
                        {
                            result.dbReturningState = data;
                        }
                    },CommandType.StoredProcedure,false);
                return result;
            });
        }
    }
}
